try {var dummy = EventBroadcaster} catch(e){


function EventBroadcaster(){
}

var proto = EventBroadcaster.prototype;

/**
 * addListener registers the listener object as interested in receiving
 * events associated with a method name. For example:
 *   application.rtcf.addListener("onConnect", myComponent);
 * means that the myComponent.onConnect(event) method will be called
 * whenever the framework dispatches an onConnect event.
 *
 * Since a unique listener._hID_ property is required to register
 * a listener it is added automatically to the listener by the
 * getHashID method if the listener doesn't have an _hID_ property already.
 */
proto.addListener = function(methodName, listener){
	if (! methodName){
		trace("ERROR: Can't addListener without a method name.");
		return;
	}
	
	if (typeof listener != "object" || ! listener){
		trace("ERROR: Can't addListener without a listener object.");
		return;
	}
	
	var hashID = EventBroadcaster.getHashID(listener);
	var methodListeners = this.getMethodListeners(methodName);
	
	methodListeners[hashID] = listener;
}

/**
 * removeListener removes the listener object so that it no longer
 * recieves events of related to the methodName.
 */
proto.removeListener = function(methodName, listener){
	if (! methodName){
		trace("ERROR: Can't removeListener without a method name.");
		return;
	}
	
	if (typeof listener != "object" || ! listener){
		trace("ERROR: Can't removeListener without a listener object.");
		return;
	}
	
	var hashID = EventBroadcaster.getHashID(listener);
	var methodListeners = this.getMethodListeners(methodName);
	
	delete methodListeners[hashID];
}

/** 
 * Since a unique listener._hID_ property is required to register
 * a listener it is added automatically to the listener by the
 * getHashID method if the listener doesn't have an _hID_ property already.
 */
EventBroadcaster.getHashID = function(listener){
	
	if (typeof listener != "object" || ! listener){
		trace("ERROR: Can't get hash ID on a non-object.");
		return;
	}
	
	var hashID = listener._hID_;
	
	if (! hashID) {
		var id = EventBroadcaster.nextID++;
		hashID = id.toString(36);
		listener._hID_ = hashID;
	}
	
	return hashID;
}


/** 
 * A broadcaster may have any number of events it has to broadcast.
 * To remember which listeners are interested in each event it must
 * keep track of listeners by event name (ie methodName). 
 * A nested hash (Associative Array) structure is used that can be
 * summarized this way:
 *
 *    this._methodListeners_ = {
 *       methodName1: {
 *          someHashID: someListenerReference,
 *          anotherHashID: anotherListenerReferece
 *       },
 *       methodName2: {
 *          someHashID: someListenerReference,
 *          anotherHashID: anotherListenerReferece
 *       }
 *    }
 *
 * The getMethodListeners returns a nested hash for a methodName.
 * The structure that is returned can be summarized this way:
 *
 *    someMethodName: {
 *       hashID1: listenerReference1,
 *       hashID2: listenerReference2
 *    }
 */
proto.getMethodListeners = function(methodName){
	if (! methodName){
		trace("ERROR: Can't getMethodListeners without a method name.");
		return;
	}
	
	if (! this._methodListeners_) this._methodListeners_ = {};
	if (! this._methodListeners_[methodName]) this._methodListeners_[methodName] = {};
	
	return this._methodListeners_[methodName];
}

proto.getListenerRegistrationCount = function(methodName){
	if (! methodName){
		trace("ERROR: Can't getListenerRegistrationCount without a method name.");
		return;
	}
	
	if (! this._methodListeners_) {
		return 0;
	}
	
	if (! this._methodListeners_[methodName]) {
		return 0;
	}
	
	var listeners =  this._methodListeners_[methodName];
	var count = 0;
	for (var p in listeners) {
		++count;
	}
	
	return count;
}

proto.getActiveListenerCount = function(methodName){
	if (! methodName){
		trace("ERROR: Can't getActiveListenerCount without a method name.");
		return;
	}
	
	if (! this._methodListeners_) {
		return 0;
	}
	
	if (! this._methodListeners_[methodName]) {
		return 0;
	}
	
	var listeners =  this._methodListeners_[methodName];
	var count = 0;
	for (var p in listeners) {
		if(listeners[p][methodName]) {
			++count;
		}
	}
	
	return count;
}

/**
 * This method dispatches the event to all the interested listeners.
 * It doesn't do anything with return values that a listener may return
 * when its method is called.
 */
proto.broadcastEvent = function(methodName){
	if (! methodName){
		trace("ERROR: Can't broadcast event without a method name.");
		return;
	}
	
	var args = [];
	
	for (var i = 1; i < arguments.length; i++){
		args.push(arguments[i]);
	}
	
	var methodListeners = this.getMethodListeners(methodName); 
	for (var hashID in methodListeners) {
		var listener = methodListeners[hashID];
		var method = listener[methodName];
		if (method){
			method.apply(listener, args);
		}
	}
}

/**
 * broadcast the event but also keep and return an array
 * of results returned from each method called.
 */
proto.broadcastEventReturnResults = function(methodName){
	if (! methodName){
		trace("ERROR: broadcastEventReturnResults: Can't broadcast event without a method name.");
		return;
	}
	
	var args = [];
	
	for (var i = 1; i < arguments.length; i++){
		args.push(arguments[i]);
	}
	
	var results = [];
	
	var methodListeners = this.getMethodListeners(methodName); 
	for (var hashID in methodListeners) {
		var listener = methodListeners[hashID];
		var method = listener[methodName];
		if (method){
			results.push( method.apply(listener, args) );
		}
	}
	
	return results;
}

// Used to generate unique id for listeners:
EventBroadcaster.nextID = 1;

/**
 * init initializes an object by "mixing in" methods 
 * that from the EventBroadcaster class.
 */
EventBroadcaster.init = function(broadcaster){
	if (typeof broadcaster != "object" || ! broadcaster){
		trace("ERROR: Can't init a broadcaster unless it is an object.");
		return;
	}
	
	var proto = EventBroadcaster.prototype;
	var methodNames = ["addListener", "removeListener", "getMethodListeners", 
			"getHashID", "broadcastEvent", "broadcastEventReturnResults", "broadcastEventReturnBoolean",
			"getListenerRegistrationCount", "getActiveListenerCount"];
	for (var i = 0; i < methodNames.length; i++){
		var methodName = methodNames[i];
		broadcaster[methodName] = proto[methodName];
	}
}


}